package com.aifast.system.sys.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.aifast.common.base.R;
import com.aifast.common.global.Const;
import com.aifast.common.layui.LayuiDataTable;
import com.aifast.common.layui.LayuiPageFactory;
import com.aifast.common.util.AiUtil;
import com.aifast.common.util.FileTypeUtil;
import com.aifast.system.sys.dao.SysFileDao;
import com.aifast.system.sys.entity.SysFile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 文件存储Service业务层处理
 *
 * @author fujian
 * @date 2022-08-31
 */
@Service
@RequiredArgsConstructor
public class SysFileService extends ServiceImpl<SysFileDao, SysFile> {
    private final SysFileDao dao;

    /**
     * layui数据表格列表查询方法
     * <br>这里参数不使用参数类，当超过5个参数时筛选条件参数建议使用参数类param封装
     *
     * @param page   分页
     * @return 列表数据
     */
    public LayuiDataTable list(SysFile pm, Page page) {
        LambdaQueryWrapper<SysFile> wrapper = new LambdaQueryWrapper<SysFile>()
                .like(StrUtil.isNotBlank(pm.getName()), SysFile::getName, pm.getName())
                .eq(ObjectUtil.isNotNull(pm.getType()), SysFile::getType, pm.getType())
                .eq(StrUtil.isNotBlank(pm.getRelationTable()), SysFile::getRelationTable, pm.getRelationTable())
                .eq(ObjectUtil.isNotNull(pm.getRelationId()), SysFile::getRelationId, pm.getRelationId())
                .orderByDesc(SysFile::getId);
        return LayuiPageFactory.init(page(page, wrapper));
    }


    /**
     * 新增或者修改
     * <br>vo的方法另写，里面有判定是否新增还是修改 可自定义逻辑
     *
     * @param sysFile
     * @return
     */
    @Transactional
    public Boolean insertOrUpdate(SysFile sysFile) {
        if (ObjectUtil.isNull(sysFile.getId())) {

        }
        return saveOrUpdate(sysFile);
    }

    /**
     * 删除方法
     * <br>提供单个删除和批量删除
     *
     * @param id  数据id
     * @param ids 数据id集合
     * @return
     */
    public Boolean del(Integer id, String ids) {
        List<Integer> list = new ArrayList<>();
        if (StrUtil.isNotBlank(ids)) {
            list = Convert.toList(Integer.class, ids.split(","));
        }
        if (ObjectUtil.isNotNull(id)) {
            list.add(id);
        }
        try {
            list.forEach(i -> {
                update(new UpdateWrapper<SysFile>().set("deleted", true).eq("id", i));
            });
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 数据详情
     *
     * @param id 数据id
     * @return
     */
    public R info(Integer id) {
        if (ObjectUtil.isNull(id)) return R.ERROR();
        SysFile one = getById(id);
        return R.OK(one);
    }


    public boolean upload(MultipartFile file, String tableName, Integer customerId) throws IOException {
        String[] strings = file.getOriginalFilename().split(Const.SYMBOL_SPOT);
        String fileName = StrUtil.join("_", new Date().getTime(), strings[0]);
        String tmpType = strings[strings.length - 1];
        String type = FileTypeUtil.getFileOfType(tmpType);

        String filePath = StrUtil.join("/", "bucket", type, fileName + "." + tmpType);
        String realPath = Const.CURRTPATH + filePath;
        file.transferTo(new File(realPath));

        SysFile build = SysFile.builder().filePath(filePath).name(fileName).size(file.getSize()).realPath(realPath)
                .format(tmpType).type(type).relationTable(tableName).relationId(customerId.longValue()).build();

        return save(build);

    }

    public R simpleUpload(MultipartFile file, String tableName)  throws IOException{
        String[] strings = file.getOriginalFilename().split(Const.SYMBOL_SPOT);
        String fileName = StrUtil.join("_", new Date().getTime(), strings[0]);
        String tmpType = strings[strings.length - 1];
        String type = FileTypeUtil.getFileOfType(tmpType);
        String filePath = StrUtil.join("/", "bucket", type, fileName + "." + tmpType);
        String realPath = Const.CURRTPATH + filePath;
        file.transferTo(new File(realPath));

        SysFile build = SysFile.builder().filePath(filePath).name(fileName).size(file.getSize()).realPath(realPath)
                .format(tmpType).type(type).relationTable(tableName).build();

        return save(build) ? R.OK(build) : R.ERROR();

    }

    /**
     * 重名文文件
     * @param id
     * @param name
     * @return
     */
    public boolean rename(Integer id, String name) {
        if(StrUtil.isBlank(name)){
            return false;
        }
        SysFile file = getById(id);
        File rename = FileUtil.rename(new File(file.getRealPath()), name, true, true);
        String absolutePath = rename.getAbsolutePath();
        String format = "";
        String[] split = file.getFilePath().split("/");
        String[] split1 = split[split.length - 1].split(Const.SYMBOL_SPOT);
        if(StrUtil.isNotBlank(file.getFormat())){
            format = file.getFormat();
        }else {
            format = split1[1];
        }
        String join = StrUtil.join("/", split[0], split[1], name + "." + format);
        file.setName(name);
        file.setRealPath(absolutePath);
        file.setFilePath(join);

        return updateById(file) ;
    }

    public void download(Integer id, HttpServletRequest request, HttpServletResponse response) throws IOException {
        SysFile sysFile = getById(id);
        if(ObjectUtil.isNull(sysFile) || StrUtil.isBlank(sysFile.getRealPath())){
            AiUtil.alert("文件不存在！！！");
        }
        request.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] bytes = FileUtil.readBytes(sysFile.getRealPath());
        response.setContentType("application/octet-stream");
        String fileName = new String(sysFile.getName().getBytes("UTF-8"), "ISO8859-1");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + "." + sysFile.getFormat());
        outputStream.write(bytes);
        IoUtil.close(outputStream);
    }


}
